package com.jinke.api.modules.ums.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jinke.api.common.api.CommonPage;
import com.jinke.api.common.api.CommonResult;
import com.jinke.api.modules.app.enums.ChannelStatus;
import com.jinke.api.modules.ums.mapper.ChannelMapper;
import com.jinke.api.modules.ums.model.*;
import com.jinke.api.modules.ums.request.GetChannelRequest;
import com.jinke.api.modules.ums.request.UserChannelRequest;
import com.jinke.api.modules.ums.service.*;
import com.jinke.api.modules.ums.vo.UserChannelVO;
import com.jinke.api.security.util.AdminUserUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 后台管理员管理Service实现类
 * Created by macro on 2018/4/26.
 */
@Service
public class ChannelServiceImpl extends ServiceImpl<ChannelMapper, Channel> implements ChannelService {

    @Autowired
    private UserChannelService userChannelService;
    @Resource
    private ChannelPlatformService channelPlatformService;
    @Resource
    private ChannelService channelService;
    @Resource
    private ChannelCarrierService channelCarrierService;
    @Resource
    private UmsAdminService umsAdminService;

    /**
     * 查询用户的渠道，只返回当前状态是开的渠道
     * @param userId
     * @param channelCode
     * @param channelId
     * @return
     */
    @Override
    public List<UserChannelVO> getOnChannels(Integer userId, String channelCode, Integer channelId) {
        // 获取用户权限
        List<UserChannel> userChannels = userChannelService.list(new LambdaQueryWrapper<UserChannel>()
                .eq(UserChannel::getUserId, userId)
        );
        if (CollectionUtil.isEmpty(userChannels)) {
            return new ArrayList<>();
        }

        //根据渠道id 获取渠道列表
        List<Channel> channels = list(new LambdaQueryWrapper<Channel>()
                .eq(StringUtils.isNotBlank(channelCode), Channel::getChannelCode, channelCode)
                .eq(Channel::getStatus, ChannelStatus.ON)
                .eq(channelId != null, Channel::getId, channelId)
                .in(Channel::getId, userChannels.stream().map(UserChannel::getChannelId).collect(Collectors.toList()))
        );

        Map<Integer, Channel> channelMap = channels.stream()
                .collect(Collectors.toMap(Channel::getId, Function.identity()));

        List<UserChannelVO> userChannelVOS = new ArrayList<>();
        for (UserChannel userChannel : userChannels) {
            UserChannelVO userChannelVO = new UserChannelVO();
            BeanUtils.copyProperties(userChannel, userChannelVO);
            Channel channel = channelMap.get(userChannelVO.getChannelId());
            if (channel == null) {
                continue;
            }
            userChannelVO.setChannel(channel);
            userChannelVOS.add(userChannelVO);
        }

        return userChannelVOS;

    }

    /**
     * 通过主键查渠道
     *
     * @param channelId
     * @return
     */
    @Override
    public UserChannelVO getChannelById(Integer userId,Integer channelId) {
        UserChannelVO userChannelVO = new UserChannelVO();
        // 获取用户权限
        UserChannel userChannel = userChannelService.getOne(new LambdaQueryWrapper<UserChannel>()
                .eq(UserChannel::getUserId, userId)
                .eq(UserChannel::getChannelId, channelId)
        );
        BeanUtils.copyProperties(userChannel, userChannelVO);
        //根据渠道id 获取渠道列表
        Channel channel = getOne(new LambdaQueryWrapper<Channel>()
                .eq(Channel::getId, channelId)
        );

        userChannelVO.setChannel(channel);

        return userChannelVO;
    }

    /**
     * 通过serviceCode查用户授权的开着的渠道
     * @param serviceCode 可为空
     * @return
     */
    @Override
    public List<UserChannelVO> getOnChannelsByUserIdAndServiceCode( String serviceCode) {
        UmsAdmin userInfo = AdminUserUtil.getUserInfo();
        // 获取用户权限
        List<UserChannel> userChannels = userChannelService.list(new LambdaQueryWrapper<UserChannel>()
                .eq(UserChannel::getUserId, userInfo.getId())
        );
        if (CollectionUtil.isEmpty(userChannels)) {
            return new ArrayList<>();
        }

        //根据渠道id 获取渠道列表 开通的
        List<Channel> channels = list(new LambdaQueryWrapper<Channel>()
                .eq(StringUtils.isNotBlank(serviceCode), Channel::getServiceCode, serviceCode)
                .eq(Channel::getStatus, ChannelStatus.ON)
                .in(Channel::getId, userChannels.stream().map(UserChannel::getChannelId).collect(Collectors.toList()))
        );

        Map<Integer, Channel> channelMap = channels.stream()
                .collect(Collectors.toMap(Channel::getId, Function.identity()));

        List<UserChannelVO> userChannelVOS = new ArrayList<>();
        for (UserChannel userChannel : userChannels) {
            UserChannelVO userChannelVO = new UserChannelVO();
            BeanUtils.copyProperties(userChannel, userChannelVO);
            Channel channel = channelMap.get(userChannelVO.getChannelId());
            if (channel == null) {
                continue;
            }
            userChannelVO.setChannel(channel);
            userChannelVOS.add(userChannelVO);
        }

        return userChannelVOS;

    }

    /**
     * 查询用户的授权渠道
     * @param request
     * @return
     */
    @Override
    public CommonResult<CommonPage<UserChannelVO>> getUserChannel(UserChannelRequest request) {
        Integer userId = request.getUserId();
        Page<UserChannel> page = new Page<>(request.getPageNum(), request.getPageSize());
        LambdaQueryWrapper<UserChannel> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(userId != null, UserChannel::getUserId, userId);
        Page<UserChannel> pageResult = userChannelService.page(page, wrapper);
        Page<UserChannelVO> pageVOResult = new Page<>();
        BeanUtils.copyProperties(pageResult, pageVOResult);
        List<UserChannel> userChannels = pageResult.getRecords();
        List<UserChannelVO> userChannelVOS = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(userChannels)) {

            Set<Integer> userIds = userChannels.stream().map(UserChannel::getUserId).collect(Collectors.toSet());
            Map<Integer, String> userMap = umsAdminService.list(new LambdaQueryWrapper<UmsAdmin>().in(UmsAdmin::getId, userIds))
                    .stream().collect(Collectors.toMap(UmsAdmin::getId, UmsAdmin::getUsername));


            Set<Integer> channelIds = userChannels.stream().map(UserChannel::getChannelId).collect(Collectors.toSet());
            List<Channel> channels = channelService.list(new LambdaQueryWrapper<Channel>()
                    .eq(Channel::getStatus, ChannelStatus.ON)
                    .like(StringUtils.isNotEmpty(request.getChannelName()), Channel::getChannelName, request.getChannelName())
                    .in(Channel::getId, channelIds));
            Map<Integer, Channel> channelMap = channels.stream()
                    .collect(Collectors.toMap(Channel::getId, Function.identity()));

            Set<Integer> channelPlatformIds = userChannels.stream().map(UserChannel::getChannelPlatformId).collect(Collectors.toSet());
            Map<Integer, String> channelPlatformMap = channelPlatformService.list(new LambdaQueryWrapper<ChannelPlatform>()
                            .in(ChannelPlatform::getId, channelPlatformIds))
                    .stream().collect(Collectors.toMap(ChannelPlatform::getId, ChannelPlatform::getChannelPlatformName));

            Set<Integer> channelCarrierIds = userChannels.stream().map(UserChannel::getChannelCarrierId).collect(Collectors.toSet());
            Map<Integer, String> channelCarrierMap = channelCarrierService.list(new LambdaQueryWrapper<ChannelCarrier>()
                            .in(ChannelCarrier::getId, channelCarrierIds))
                    .stream().collect(Collectors.toMap(ChannelCarrier::getId, ChannelCarrier::getChannelCarrierName));

            for (UserChannel userChannel : userChannels) {
                UserChannelVO userChannelVO = new UserChannelVO();
                BeanUtils.copyProperties(userChannel, userChannelVO);
                userChannelVO.setUsername(userMap.get(userChannelVO.getUserId()));
                Channel channel = channelMap.get(userChannelVO.getChannelId());
                if (channel == null) {
                    continue;
                }
                userChannelVO.setChannelName(channel.getChannelName());
                userChannelVO.setServiceCode(channel.getServiceCode());
                userChannelVO.setChannelCode(channel.getChannelCode());
                userChannelVO.setChannelPlatFormName(channelPlatformMap.get(channel.getChannelPlatformId()));
                userChannelVO.setChannelCarrierName(channelCarrierMap.get(channel.getChannelCarrierId()));
                userChannelVOS.add(userChannelVO);
            }

            pageVOResult.setRecords(userChannelVOS);
        }

        return CommonResult.success(CommonPage.restPage(pageVOResult));
    }

    /**
     * 通过渠道id查下级服务
     * @param
     * @return
     */
    @Override
    public List<Channel> getServiceByChannelIds(List<Integer> channelIds) {
        List<Channel> channels = channelService.list(new LambdaQueryWrapper<Channel>()
                .in(Channel::getChannelCarrierId, channelIds));
        return channels;
    }

    /**
     * 通过主键批量拓展查询
     *
     * @param ids
     * @return
     */
    @Override
    public List<Channel> getChannelByPKs(Set<Integer> ids) {
        List<Channel> channels = channelService.list(new LambdaQueryWrapper<Channel>()
                .in(Channel::getId, ids));
        return channels;    }

    @Override
   // @Cacheable(cacheNames = "channelPageByPlatformIdCarrierId", key = "#request.channelPlatformId + ':' + #request.channelCarrierId + ':' + #request.pageNum + ':' + #request.pageSize")
    public Page<Channel> pageList(GetChannelRequest request) {
        Page<Channel> page = new Page<>(request.getPageNum(), request.getPageSize());
        LambdaQueryWrapper<Channel> wrapper = new LambdaQueryWrapper<>();



//        wrapper.select(Channel::getChannelId, Channel::getChannelId
//
//                , Channel::getStatus
//                , Channel::getChannelName
//                , Channel::getChannelCode
//                , Channel::getServiceCode
//                , Channel::getChannelPlatformId, Channel::getId
//
//
//        );
        wrapper.eq(request.getChannelPlatformId() != null, Channel::getChannelPlatformId, request.getChannelPlatformId());
        wrapper.eq(request.getChannelCarrierId() != null, Channel::getChannelCarrierId, request.getChannelCarrierId());
        return channelService.page(page, wrapper);
    }


}
